package com.qinsoft.frame.taobao.recom;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.qinsoft.business.recom.bean.Recom;
import com.qinsoft.business.recom.bean.RecomItem;
import com.qinsoft.business.recom.dao.RecomDao;
import com.qinsoft.business.recomlog.bean.RecomLog;
import com.qinsoft.business.recomlog.dao.RecomLogDao;
import com.qinsoft.business.task.bean.Task;
import com.qinsoft.business.task.dao.TaskDao;
import com.qinsoft.business.user.bean.User;
import com.qinsoft.business.user.dao.UserDao;
import com.qinsoft.frame.constants.QinCodeConstants;
import com.qinsoft.frame.exception.ApiException;
import com.qinsoft.frame.taobao.task.TaskException;
import com.qinsoft.frame.utils.EmptyUtils;
import com.qinsoft.frame.utils.ItemChain;
import com.qinsoft.frame.utils.TaobaoInter;
import com.taobao.api.domain.Item;
import com.taobao.api.domain.Shop;
import com.taobao.api.response.ItemRecommendAddResponse;
import com.taobao.api.response.ItemRecommendDeleteResponse;
import com.taobao.api.response.ItemsOnsaleGetResponse;
import com.taobao.api.response.ShopRemainshowcaseGetResponse;
import com.taobao.api.response.TraderatesGetResponse;

/**
 * 自动橱窗 自动任务
 * @author zhoujian
 *
 */
public class RecomTask implements Runnable{
	private final String SALE = "recom";

    private Integer index = 0;
    private int pageSize = 50;//每页多少数据
    private TaskDao taskDao = new TaskDao();
    private int total = 0;//总数
    private RecomDao recomDao = new RecomDao();
    private List<Recom> list = new ArrayList<Recom>();
    
    @Override
    public void run()
    {
        while (true)
        {
            try
            {
                start();
                Thread.sleep(QinCodeConstants.SALE_FIXED_TIME);
            }
            catch (Exception e)
            {
                TaskException.getResultMessage(e);
            }
        }
    }
    
    /**
     * 初始化
     */
    public void init()
    {
        index = 0;
        if(taskDao.exist(SALE))
        {
            Task tasks = taskDao.select(SALE);
            index = tasks.getNowPosition();
        }
        total = recomDao.selectAutoRecomTotal(index);
    }
    
    /**
     * 具体执行任务
     * @throws InterruptedException 
     */
    public void start() throws InterruptedException
    {
        init();
        //设置每一页要显示多少条记录 
        int allpages=0;
        allpages = (total%pageSize==0)?(total/pageSize):((total/pageSize)+1);
        int pageNo = index;
        for(int i=0;i<allpages;i++)
        {
        	list = new ArrayList<Recom>();
        	list = recomDao.selectAutoRecom((pageNo+i*pageSize),pageSize);
        	for(int j=0; list!=null && j<list.size(); j++,index++)
            {
                try
                {
                    //处理过程
                	//获取用户
                	User user = UserDao.getUser(list.get(j).getNick());
                	//判断权限及sessionkey有效期
                	try {
                		int limit = Integer.parseInt(user.getPermit().substring(0, 3));
                		//权限通过
                		if(limit==1&&user.getDeadline().after(new Date())){
                			//获取推荐范围
                			String type = list.get(j).getRecomType();
                			String reshToken = user.getReshToken();
                			//获取店铺橱窗信息
                			int allCount = 10;
                			Shop shop = getRecomNum(reshToken);
                			if(!EmptyUtils.isEmpty(shop)&&!EmptyUtils.isEmpty(shop.getAllCount())){
                				allCount = shop.getAllCount().intValue();
                				//更新数据库里橱窗
                				Recom recom = list.get(j);
                				recom.setRecomSize(allCount+0L);
                				recomDao.save(recom);
                			}else{
                				if(!EmptyUtils.isEmpty(list.get(j).getRecomSize())){
                					allCount = list.get(j).getRecomSize().intValue();
                				}
                			}
                			if(!EmptyUtils.isEmpty(list.get(j))){
                    			//不推荐多少分钟内就要下架的宝贝(如果用户没有选择默认为0)
                        		if(EmptyUtils.isEmpty(list.get(j).getRecomTime())){
                        			list.get(j).setRecomTime(0L);
                        		}
                        		//不推荐所剩数量低于多少件的宝贝(如果用户没有设置默认为0)
                        		if(EmptyUtils.isEmpty(list.get(j).getRecomCount())){
                        			list.get(j).setRecomCount(0L);
                        		}
                    		}
                			if("sale".equals(type)){//出售商品
                				dealOnsaleItem(allCount, reshToken, list.get(j));
                			}else if("itemCat".equals(type)){//类目商品
                				dealCatItem(allCount,reshToken, list.get(j));
                			}else if("item".equals(type)){//指定商品
                				dealAppointItem(allCount,reshToken,list.get(j));
                			}
                		}
					} catch (Exception e) {
					}
                }
                catch (Exception e)
                {
                    TaskException.getResultMessage(this.getClass().toString()+".start("+ list.get(i).getNick() +")",e);
                }
            }
        }
    }
    //处理指定商品推广
    public void dealAppointItem(int allCount,String sessionKey,Recom recom){
    	RecomDao recomDao = new RecomDao();
    	//获取指定推荐商品
    	List<RecomItem> list = recomDao.selectItemByLimit(recom.getNick(), 1, allCount);
    	if(!EmptyUtils.isEmptyList(list)){
    		//转成Item对象
    		List<Item> items = new ArrayList<Item>();
    		for(RecomItem ritem : list){
    			Item item = new Item();
    			item.setNumIid(ritem.getNumIid());
    			items.add(item);
    		}
    		//补商品
    		if(items.size()<allCount){
    			List<Item> addlist = new ArrayList<Item>();
    			int needNum = allCount-items.size();
    			//获取推荐方式
    			String recomMode = recom.getRecomMode();
    			//获取不推荐的商品
    			List<RecomItem> nolist = recomDao.selectItemByState(recom.getNick(), 0);
    			//转成Item对象
        		List<Item> noitems = new ArrayList<Item>();
    			if(!EmptyUtils.isEmptyList(nolist)){
    				for(RecomItem ritem : nolist){
    	    			Item item = new Item();
    	    			item.setNumIid(ritem.getNumIid());
    	    			noitems.add(item);
    	    		}
    			}
    			ItemChain chain = new ItemChain();
    			chain.addAllNode(items);
    			ItemChain nochain = new ItemChain();
    			nochain.addAllNode(noitems);
        		if("down".equals(recomMode)){//即将下架的商品
        			addlist = recursionItem(0,needNum,needNum,sessionKey,recom,chain,nochain,new ArrayList<Item>());
        		}else if("hot".equals(recomMode)){//热销商品
        			addlist = getHotSale(needNum, sessionKey, recom, chain, nochain);
        		}
        		for(Item item : addlist){
    				items.add(item);
    			}
    		}
    		//推荐商品
			addRecomItems(items, sessionKey, recom.getNick());
    	}
    }
    //处理类目推广
    public void dealCatItem(int allCount,String sessionKey,Recom recom){
    	//类目id串
    	String cats = recom.getItemCat();
    	if(!EmptyUtils.isEmpty(cats)){
    		List<StringBuffer> catlist = new ArrayList<StringBuffer>();
    		if(cats.split(",").length>32){
    			try {
    				String[] strs = cats.split(",");
        			int num=0;
    		        num = (strs.length%32==0)?(strs.length/32):((strs.length/32)+1);
    		        for(int i=0;i<num;i++){
    		        	int index = 0;
    		        	StringBuffer sb = new StringBuffer();
    		        	for(int j=i*32;j<strs.length;j++,index++){
    		        		if(index==32){
    		        			break;
    		        		}
    		        		if(j==(32*i+1)){
    		        			sb.append(strs[j]);
    		        		}else if(j==strs.length-1){
    		        			sb.append(strs[j]);
    		        		}else{
    		        			sb.append(strs[j]+",");
    		        		}
    		        	}
    		        	catlist.add(sb);
    		        }
				} catch (Exception e) {
				}
    		}else{
    			catlist.add(new StringBuffer(cats));
    		}
    		List<Item> reslist = new ArrayList<Item>();
    		//调用接口获取商品
    		for(int i=0;i<catlist.size();i++){
    			//获取商品总数
    			Map<String, Object> map = new HashMap<String, Object>();
    			map.put("seller_cids", catlist.get(i).toString());
    			String alltql = "select num_iid from taobao.items.onsale.get where has_showcase=false and seller_cids=#seller_cids#";
    			try {
					ItemsOnsaleGetResponse res = TaobaoInter.sendInter(alltql, sessionKey, ItemsOnsaleGetResponse.class,map);
					if(!EmptyUtils.isEmpty(res)&&!EmptyUtils.isEmpty(res.getTotalResults())){
						int total = res.getTotalResults().intValue();
						int allpages=0;
				        allpages = (total%pageSize==0)?(total/pageSize):((total/pageSize)+1);
				        for(int j=0;j<allpages;j++){
				        	String tql = "select num_iid,num,title,delist_time from taobao.items.onsale.get where has_showcase=false and page_no="+j+" and page_size="+pageSize+" and seller_cids=#seller_cids#";
				        	ItemsOnsaleGetResponse itemres = TaobaoInter.sendInter(tql, sessionKey, ItemsOnsaleGetResponse.class,map);
				        	if(!EmptyUtils.isEmpty(itemres)&&!EmptyUtils.isEmpty(itemres.getItems())){
				        		//处理数据
				        		List<Item> list = itemres.getItems();
				        		for(int z=0;z<list.size();z++){
				            		try {
				            			//不推荐多少分钟内就要下架的宝贝(如果用户没有选择默认为0)
				                		if(list.get(z).getDelistTime().getTime()-new Date().getTime()<recom.getRecomTime().intValue()*60000){
				                			list.remove(z);
				                			continue;
				                		}
				                		//不推荐所剩数量低于多少件的宝贝(如果用户没有设置默认为0)
				                		if(list.get(z).getNum().intValue()<recom.getRecomCount().intValue()){
				                			list.remove(z);
				                			continue;
				                		}
				                		if(recom.getOverSix()){
				                			//强制取消剩余时间超过6天半的宝贝(勾选可防止出现系统推荐刚刚上架的宝贝)
				                			if(list.get(z).getDelistTime().getTime()-new Date().getTime()<6.5*86400000){
				                				list.remove(z);
				                				continue;
				                			}
				                		}
				                		if(reslist.size()>=allCount){
				                			break;
				                		}
				                		reslist.add(list.get(z));
				        			} catch (Exception e) {
				        				list.remove(z);
				        				continue;
				        			}
				            	}
				        	}
				        }
					}
				} catch (ApiException e) {
					//TODO 记录日志
					e.printStackTrace();
				}
    		}
    		//取推荐方式
    		String recomMode = recom.getRecomMode();
    		//商品是否满了
    		if(reslist.size()<allCount){
    			//需要添加商品 添加出售中的商品
    			List<Item> addlist = new ArrayList<Item>();
    			int needNum = allCount-reslist.size();
    			ItemChain chain = new ItemChain();
    			chain.addAllNode(reslist);
    			if("down".equals(recomMode)){//即将下架的商品
    				addlist = recursionItem(0,needNum,needNum,sessionKey,recom,chain,new ItemChain(),new ArrayList<Item>());
    			}else if("hot".equals(recomMode)){//热销商品
    				addlist = getHotSale(needNum, sessionKey, recom, chain, new ItemChain());
    			}
    			for(Item item : addlist){
    				reslist.add(item);
    			}
    		}
    		//推荐商品
	        addRecomItems(reslist, sessionKey, recom.getNick());
    	}
    }
    //处理onsale商品
    public void dealOnsaleItem(int allCount,String sessionKey,Recom recom){
    	//取推荐方式
		String recomMode = recom.getRecomMode();
		if("down".equals(recomMode)){//即将下架的商品
			//获取商品总数
			String alltql = "select num_iid from taobao.items.onsale.get where has_showcase=false";
			try {
				ItemsOnsaleGetResponse res = TaobaoInter.sendInter(alltql, sessionKey, ItemsOnsaleGetResponse.class);
				if(!EmptyUtils.isEmpty(res)&&!EmptyUtils.isEmpty(res.getTotalResults())){
					int total = res.getTotalResults().intValue();
					int allpages=0;
			        allpages = (total%pageSize==0)?(total/pageSize):((total/pageSize)+1);
			        List<Item> reslist = new ArrayList<Item>();
			        for(int i=0;i<allpages;i++){
			        	String tql = "select num_iid,num,title,delist_time from taobao.items.onsale.get where has_showcase=false and page_no="+i+" and page_size="+pageSize+" order_by delist_time:asc";
			        	ItemsOnsaleGetResponse itemres = TaobaoInter.sendInter(tql, sessionKey, ItemsOnsaleGetResponse.class);
			        	if(!EmptyUtils.isEmpty(itemres)&&!EmptyUtils.isEmpty(itemres.getItems())){
			        		//处理数据
			        		List<Item> items = itemres.getItems();
			        		for(int j=0;j<items.size();j++){
			            		try {
			            			//不推荐多少分钟内就要下架的宝贝(如果用户没有选择默认为0)
			                		if(items.get(j).getDelistTime().getTime()-new Date().getTime()<recom.getRecomTime().intValue()*60000){
			                			items.remove(j);
			                			continue;
			                		}
			                		//不推荐所剩数量低于多少件的宝贝(如果用户没有设置默认为0)
			                		if(items.get(j).getNum().intValue()<recom.getRecomCount().intValue()){
			                			items.remove(j);
			                			continue;
			                		}
			                		if(recom.getOverSix()){
			                			//强制取消剩余时间超过6天半的宝贝(勾选可防止出现系统推荐刚刚上架的宝贝)
			                			if(items.get(j).getDelistTime().getTime()-new Date().getTime()<6.5*86400000){
			                				items.remove(j);
			                				continue;
			                			}
			                		}
			                		if(reslist.size()>=allCount){
			                			break;
			                		}
			                		reslist.add(items.get(j));
			        			} catch (Exception e) {
			        				items.remove(j);
			        				continue;
			        			}
			            	}
			        	}
			        }
			        //推荐商品
			        addRecomItems(reslist, sessionKey, recom.getNick());
				}
			} catch (ApiException e) {
				//TODO 记录日志
				e.printStackTrace();
			}
		}else if("hot".equals(recomMode)){//热销商品
			List<Item> items = getHotSale(allCount, sessionKey, recom, new ItemChain(), new ItemChain());
			//推荐商品
	        addRecomItems(items, sessionKey, recom.getNick());
		}
    }
    //如果选择了热销 通过获取评价数来判断是否热销
    @SuppressWarnings("unchecked")
	public List<Item> getHotSale(int needNum,String sessionKey,Recom recom,ItemChain itemchain,ItemChain nochain){
    	List<Item> list = new ArrayList<Item>();
    	//获取商品总数
		String alltql = "select num_iid from taobao.items.onsale.get where has_showcase=false";
		try {
			ItemsOnsaleGetResponse res = TaobaoInter.sendInter(alltql, sessionKey, ItemsOnsaleGetResponse.class);
			if(!EmptyUtils.isEmpty(res)&&!EmptyUtils.isEmpty(res.getTotalResults())){
				int total = res.getTotalResults().intValue();
				int allpages=0;
		        allpages = (total%pageSize==0)?(total/pageSize):((total/pageSize)+1);
		        List<Item> reslist = new ArrayList<Item>();
		        for(int i=0;i<allpages;i++){
		        	String tql = "select num_iid,num,title,delist_time from taobao.items.onsale.get where has_showcase=false and page_no="+i+" and page_size="+pageSize+"";
		        	ItemsOnsaleGetResponse itemres = TaobaoInter.sendInter(tql, sessionKey, ItemsOnsaleGetResponse.class);
		        	if(!EmptyUtils.isEmpty(itemres)&&!EmptyUtils.isEmpty(itemres.getItems())){
		        		//处理数据
		        		List<Item> items = itemres.getItems();
		        		for(int j=0;j<items.size();j++){
		            		try {
		            			//不推荐多少分钟内就要下架的宝贝(如果用户没有选择默认为0)
		                		if(items.get(j).getDelistTime().getTime()-new Date().getTime()<recom.getRecomTime().intValue()*60000){
		                			items.remove(j);
		                			continue;
		                		}
		                		//不推荐所剩数量低于多少件的宝贝(如果用户没有设置默认为0)
		                		if(items.get(j).getNum().intValue()<recom.getRecomCount().intValue()){
		                			items.remove(j);
		                			continue;
		                		}
		                		if(recom.getOverSix()){
		                			//强制取消剩余时间超过6天半的宝贝(勾选可防止出现系统推荐刚刚上架的宝贝)
		                			if(items.get(j).getDelistTime().getTime()-new Date().getTime()<6.5*86400000){
		                				items.remove(j);
		                				continue;
		                			}
		                		}
		                		//是否已经存在
			            		if(itemchain.contains(items.get(j).getNumIid()+"")){
			            			items.remove(j);
			            			continue;
			            		}
			            		//是否已经存在在不推荐商品集合里
			            		if(nochain.contains(items.get(j).getNumIid()+"")){
			            			items.remove(j);
			            			continue;
			            		}
		                		try {
		                			//获取评价数  即销量  放到cid字段里
		                			Long rateNum = getTradeRatesNum(sessionKey, items.get(j).getNumIid());
		                			if(EmptyUtils.isEmpty(rateNum)){
		                				rateNum = 0L;
		                			}
		                			items.get(j).setCid(rateNum);
								} catch (ApiException e) {
									items.get(j).setCid(0L);
								}
		                		reslist.add(items.get(j));
		        			} catch (Exception e) {
		        				items.remove(j);
		        				continue;
		        			}
		            	}
		        	}
		        }
		        //将reslist降序排序  TODO 是否有不可预见的异常
		        Collections.sort(reslist,new Comparator(){
					@Override
					public int compare(Object arg0, Object arg1) {
						Item item0 = (Item) arg0;
						Item item1 = (Item) arg1;
						return item1.getCid().compareTo(item0.getCid());
					}
		        });
		        if(reslist.size()>needNum){
		        	//取出前面neednum个商品
		        	for(int i=0;i<needNum;i++){
		        		list.add(reslist.get(i));
		        	}
		        }else{
		        	list.addAll(reslist);
		        }
			}
		} catch (ApiException e) {
			//TODO 记录日志
			e.printStackTrace();
		}
		return list;
    }
    //即将下架 递归获取商品
    public List<Item> recursionItem(int pageNo,int pageSize,int needNum,String sessionKey,Recom recom,ItemChain itemchain,ItemChain nochain,List<Item> list){
    	//获取商品总数
    	String tql = "select num_iid,num,title,delist_time from taobao.items.onsale.get where has_showcase=false and page_no="+pageNo+" and page_size="+pageSize+" order_by delist_time:asc";
    	ItemsOnsaleGetResponse itemres;
		try {
			itemres = TaobaoInter.sendInter(tql, sessionKey, ItemsOnsaleGetResponse.class);
			if(!EmptyUtils.isEmpty(itemres)&&!EmptyUtils.isEmpty(itemres.getItems())){
	    		//处理数据
	    		List<Item> items = itemres.getItems();
	    		for(int j=0;j<items.size();j++){
	        		try {
	        			//不推荐多少分钟内就要下架的宝贝(如果用户没有选择默认为0)
	            		if(items.get(j).getDelistTime().getTime()-new Date().getTime()<recom.getRecomTime().intValue()*60000){
	            			items.remove(j);
	            			continue;
	            		}
	            		//不推荐所剩数量低于多少件的宝贝(如果用户没有设置默认为0)
	            		if(items.get(j).getNum().intValue()<recom.getRecomCount().intValue()){
	            			items.remove(j);
	            			continue;
	            		}
	            		if(recom.getOverSix()){
	            			//强制取消剩余时间超过6天半的宝贝(勾选可防止出现系统推荐刚刚上架的宝贝)
	            			if(items.get(j).getDelistTime().getTime()-new Date().getTime()<6.5*86400000){
	            				items.remove(j);
	            				continue;
	            			}
	            		}
	            		//是否已经存在
	            		if(itemchain.contains(items.get(j).getNumIid()+"")){
	            			items.remove(j);
	            			continue;
	            		}
	            		//是否已经存在在不推荐商品集合里
	            		if(nochain.contains(items.get(j).getNumIid()+"")){
	            			items.remove(j);
	            			continue;
	            		}
	            		if(list.size()>=needNum){
	            			break;
	            		}
	            		itemchain.addNode(items.get(j));
	            		list.add(items.get(j));
	    			} catch (Exception e) {
	    				items.remove(j);
	    				continue;
	    			}
	        	}
	    	}
		} catch (ApiException e1) {
			e1.printStackTrace();
		}
		if(list.size()<needNum){
			//递归调用  按理应该没错
			list = recursionItem(++pageNo,pageSize,needNum,sessionKey,recom,itemchain,nochain,list);
		}
		return list;
    }
    //获取180天内的评价数
    public Long getTradeRatesNum(String sessionKey,Long numiid) throws ApiException{
    	String tql = "select num_iid from taobao.traderates.get where rate_type=get and role=buyer and num_iid="+numiid;
    	return TaobaoInter.sendInter(tql, sessionKey, TraderatesGetResponse.class).getTotalResults();
    }
    //执行推荐商品 记录日志
    public void addRecomItems(List<Item> list,String sessionKey,String nick){
    	RecomLogDao logDao = new RecomLogDao();
    	for(Item item : list){
    		String logDetail = "";
    		String logState = "pass";
    		String tql = "insert into taobao.item.recommend.add(num_iid) values ("+item.getNumIid()+") ";
    		try {
				TaobaoInter.sendInter(tql, sessionKey, ItemRecommendAddResponse.class);
			} catch (ApiException e) {
				//再次调用
				try {
					TaobaoInter.sendInter(tql, sessionKey, ItemRecommendAddResponse.class);
				} catch (ApiException e1) {
					logState = "fail";
					logDetail = e.getMessage();
				}
			}
			//保存日志
			RecomLog log = new RecomLog(nick, logState, logDetail);
			logDao.addRomLog(log);
    	}
    }
    //取消橱窗
    //TODO 先走通功能 (取消不成功处理)
    public void removeRecomItem(String sessionKey){
    	List<Item> list;
		try {
			list = HavedRecomItem(sessionKey);
			if(!EmptyUtils.isEmptyList(list)){
	    		for(Item item : list){
	    			String tql = "delete from taobao.item.recommend.delete where num_iid="+item.getNumIid();
	    			try {
						TaobaoInter.sendInter(tql, sessionKey, ItemRecommendDeleteResponse.class);
					} catch (ApiException e) {
						//TODO 处理碰到异常
						e.printStackTrace();
					}
	    		}
	    	}
		} catch (ApiException e1) {
			e1.printStackTrace();
		}
    }
    //获取已经推荐的商品
    public List<Item> HavedRecomItem(String sessionKey) throws ApiException{
    	//TODO 橱窗是否会超过200个
    	String tql = "select num_iid from taobao.items.onsale.get where has_showcase=true and page_no=1 and page_size=200";
    	return TaobaoInter.sendInter(tql,sessionKey,ItemsOnsaleGetResponse.class).getItems();
    }
    //获取用户店铺橱窗信息
    public Shop getRecomNum(String sessionKey){
    	String tql = "select * from taobao.shop.remainshowcase.get";
    	try {
			return TaobaoInter.sendInter(tql,sessionKey,ShopRemainshowcaseGetResponse.class).getShop();
		} catch (ApiException e) {
			e.printStackTrace();
		}
		return null;
    }
    /**
     * 当服务器关闭时调用
     */
    public void stop()
    {
        Task task = new Task(SALE, 0, index, list.size());
        taskDao.insert(task);
    }
}
